/**
 * @author hugan
 * @date 2023/10/5
 */
export default {
  /**
   * 添加[类似触摸板]等需要适配[pc端.鼠标,移动端.触摸]的监听功能
   * @param {{onTouchStart,onTouchEnd,onTouchMove}} touchListener 详见代码
   */
  initListener(element, touchListener) {
    /*
      入参示例
      let listener = {
        onTouchStart(x, y, e) {
          console.log('onTouchStart', x, y, e)
        },
        onTouchEnd(e) {
          console.log('onTouchEnd', e)
        },
        onTouchMove(x, y, x0, y0, e) {
          console.log('onTouchMove', x, y, x0, y0, e)
        },
      }
      touchUtil.initListener(this.$refs.touchpad, listener)
     */

    let touchHandler = {
      isMouseDown: false,
      x0: null,
      y0: null,
      onTouchStart(type, e) {
        this.isMouseDown = true
        this.x0 = Math.floor(e.offsetX)
        this.y0 = Math.floor(e.offsetY)
        // console.log(type, e.offsetX, e.offsetY)
        touchListener.onTouchStart(Math.floor(e.offsetX), Math.floor(e.offsetY), e)
      },
      onTouchEnd(type, e) {
        this.isMouseDown = false
        // console.log(type)
        touchListener.onTouchEnd(e)
      },
      onTouchMove(type, e) {
        // console.log(type, e.offsetX, e.offsetY)
        touchListener.onTouchMove(Math.floor(e.offsetX), Math.floor(e.offsetY), this.x0, this.y0, e)
      },
      /**
       * 组件被旋转的角度[transform: rotate("result"deg);]
       * return result,如'90,-90'
       */
      getRotateDegree(){
        if (!touchListener.getRotateDegree) return 0
        return touchListener.getRotateDegree()
      },
    }

    /*
    坑不少...
    解决原生问题:
    .视频[鼠标,触摸屏]: 必须同时监听[mouse,touch]
    .丢失[点击劫持]的效果,不能保证[down-up]事件成对出现: div内[按下,移动到div外,抬起]时,收不到mouseup事件
    ...处理方式:目前只能使用[mouseleave]的方式
    .[mouseup,mousemove]都要自行过滤: 使用isMouseDown
    ...drag事件是 要设置html属性的,且拖拽时会有拖拽效果,不符合需求
    .touchend在 click操作时,会触发[mousedown,mouseup]
    .touch事件的坐标, 竟然要自己计算!!
     */
    //鼠标事件: pc端
    element.addEventListener('mousedown', e => {
      // console.log('mousedown', e)
      touchHandler.onTouchStart('mousedown', e)
    })
    element.addEventListener('mouseup', e => {
      // console.log('mouseup', e)
      if (!touchHandler.isMouseDown) return
      touchHandler.onTouchEnd('mouseup', e)
    })
    element.addEventListener('mouseleave', e => {
      // console.log('mouseleave', e)
      if (!touchHandler.isMouseDown) return
      touchHandler.onTouchEnd('mouseleave', e)
    })
    element.addEventListener('mousemove', e => {
      if (!touchHandler.isMouseDown) return
      touchHandler.onTouchMove('mousemove', e)
    })
    //触摸事件: 移动端
    element.addEventListener('touchstart', e => {
      // console.log('touchstart', e2)
      e.preventDefault()
      let e2 = this.calculateTouchPoint('touchstart', e, touchHandler)
      touchHandler.onTouchStart('touchstart', e2)
    })
    element.addEventListener('touchend', e => {
      e.preventDefault()//避免 [触击]时,会触发[mousedown,mouseup]事件
      // console.log('touchend', e)
      touchHandler.onTouchEnd('touchend', e)
    })
    element.addEventListener('touchmove', e => {
      e.preventDefault()
      let e2 = this.calculateTouchPoint('touchmove', e, touchHandler)
      touchHandler.onTouchMove('touchmove', e2)
    })
  },
  /**
   * 计算触摸事件的坐标
   * 注意: touchEvent的原生功能太坑了!!
   *  .要自己计算坐标
   *  .而且style.[position: relative, display, margin, padding]等都可能会影响计算结果!!!?
   *  .竟然可以收到 元素外的按下事件!!?? 有paddingLeft?
   *
   * @return {offsetX, offsetY} 相对于元素的坐标
   */
  calculateTouchPoint(type, touchEvent, touchHandler) {
    // console.log(type + '.e', touchEvent)
    let e2 = touchEvent.targetTouches[0]
    // console.log(type + '.e2', e2)
    // let {clientX, clientY, pageX, pageY} = e2
    // console.log(type + '.e2', clientX, clientY, pageX, pageY)

    let target = touchEvent.target
    let rect = target.getBoundingClientRect()
    // console.log(type + '.target', target.getBoundingClientRect())

    let degree = touchHandler.getRotateDegree()
    // console.log(`degree=${degree}`)
    //rotate(0deg)
    if (degree === 0) {
      e2.offsetX = e2.pageX - rect.x
      e2.offsetY = e2.pageY - rect.y
    } else if(degree === 90) {
      e2.offsetX = e2.pageY - rect.y
      e2.offsetY = rect.width - (e2.pageX - rect.x)
    } else if(degree === -90) {
      e2.offsetX = rect.height - (e2.pageY - rect.y)
      e2.offsetY = e2.pageX - rect.x
    } else {
      //应该使用数学公式...
      console.log(`未知适配角度=${degree}`)
    }

    //注意 js事件的timeStamp 都不是时间戳!!!
    e2.timeStamp = touchEvent.timeStamp
    return e2
  }

}